package sms

import (
	"context"
	"errors"
	sms2 "github.com/starmotioncf/common/sms"
	"github.com/starmotioncf/common/sms/aliyun"
	"github.com/starmotioncf/common/sms/montnets"
	"github.com/starmotioncf/common/sms/tencent"
	"github.com/starmotioncf/common/sms/whatsapp"
)

var ErrNotSupported = errors.New("not supported")

type SMSProvider uint8

const (
	SMSProviderTencent  SMSProvider = 1
	SMSProviderMontnets SMSProvider = 2
	SMSProviderAliyun   SMSProvider = 3
	SMSProviderWhatsapp SMSProvider = 4
)

type SignTemplate struct {
	Tencent    sms2.SignTemplate //腾讯的验证码模版
	Aliyun     sms2.SignTemplate //阿里云的验证码模版
	WhatsappEn sms2.SignTemplate //阿里云的验证码模版
	WhatsappAr sms2.SignTemplate //阿里云的验证码模版
	WhatsappTr sms2.SignTemplate //阿里云的验证码模版
}

type Config struct {
	Tencent  tencent.Config
	Montnets montnets.Config
	Aliyun   aliyun.Config
	Whatsapp whatsapp.Config
	Captcha  SignTemplate //验证码模版
}

type Sms struct {
	conf      Config
	providers map[SMSProvider]sms2.Provider
}

func NewSms(conf Config) (*Sms, error) {
	instances := make(map[SMSProvider]sms2.Provider)
	var err error
	instances[SMSProviderTencent], err = tencent.NewTencentSms(conf.Tencent)
	if err != nil {
		return nil, nil
	}
	instances[SMSProviderMontnets], err = montnets.NewMontnets(conf.Montnets)
	if err != nil {
		return nil, nil
	}
	instances[SMSProviderAliyun], err = aliyun.NewAliyun(conf.Aliyun)
	if err != nil {
		return nil, nil
	}
	instances[SMSProviderWhatsapp], err = whatsapp.NewWhatsapp(conf.Whatsapp)
	if err != nil {
		return nil, nil
	}
	return &Sms{
		conf:      conf,
		providers: instances,
	}, nil
}

func (s *Sms) GetProvider(p SMSProvider) (sms2.Provider, error) {
	if ins, ok := s.providers[p]; ok {
		return ins, nil
	}
	return nil, ErrNotSupported
}

// SendMsg 海外随意内容发送
func (s *Sms) SendMsg(ctx context.Context, p SMSProvider, mp *sms2.MobilePhone, msg string) (sms2.Result, error) {
	ins, err := s.GetProvider(p)
	if err != nil {
		return nil, err
	}
	return ins.Send(ctx, mp, msg)
}

// SendCaptchaByTemplate 国内服务商那种模版式发送验证码
func (s *Sms) SendCaptchaByTemplate(ctx context.Context, p SMSProvider, mp *sms2.MobilePhone, code string) (sms2.Result, error) {
	ins, err := s.GetProvider(p)
	if err != nil {
		return nil, err
	}
	var st sms2.SignTemplate
	switch p {
	case SMSProviderTencent:
		st = s.conf.Captcha.Tencent
	case SMSProviderAliyun:
		st = s.conf.Captcha.Aliyun
	case SMSProviderWhatsapp:
		st = s.conf.Captcha.WhatsappEn
		//lang := ctx.Value(constant.CtxLang)
		lang := "tr"
		switch lang {
		case "ar":
			st = s.conf.Captcha.WhatsappAr
		case "tr":
			st = s.conf.Captcha.WhatsappTr
		}
	}
	return ins.SendByTemplate(ctx, mp, st, map[string]any{"code": code})
}

// NoticeMsgByAliyun 系统提醒短信，直接走阿里云发国内短信
func (s *Sms) NoticeMsgByAliyun(ctx context.Context, mp []string, st sms2.SignTemplate, msg map[string]any) (sms2.Result, error) {
	if len(mp) == 0 {
		return nil, errors.New("empty param")
	}
	ins, err := s.GetProvider(SMSProviderAliyun)
	if err != nil {
		return nil, err
	}
	bmp := make([]*sms2.MobilePhone, len(mp))
	for i := range mp {
		bmp[i] = sms2.NewMobilePhone(86, mp[i])
	}
	return ins.BatchSendByTemplate(ctx, bmp, st, msg)
}
